/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.tencent.tendon.convert.json;

import java.lang.reflect.*;
import java.util.Map;

/**
 *
 * @author nbzhang
 */
public class JsonMapEncoder<K, V> extends JsonEncoder<Map<K, V>> {

    private final JsonEncodable<K> keyencoder;

    private final JsonEncodable<V> valencoder;

    JsonMapEncoder(final Type type) {
        super(type);
        if (type instanceof ParameterizedType) {
            final Type[] pt = ((ParameterizedType) type).getActualTypeArguments();
            this.keyencoder = JsonLoader.loadEncodable(pt[0]);
            this.valencoder = JsonLoader.loadEncodable(pt[1]);
        } else {
            this.keyencoder = (JsonEncodable<K>) JsonAnyEncoder.getInstance();
            this.valencoder = (JsonEncodable<V>) JsonAnyEncoder.getInstance();
        }
        this.simpled = valencoder.isSimpled();
    }

    public JsonMapEncoder(final Class<Map<K, V>> type, JsonEncodable<K> keyencoder, JsonEncodable<V> valencoder) {
        super(type);
        this.keyencoder = keyencoder;
        this.valencoder = valencoder;
        this.simpled = valencoder.isSimpled();
    }

    @Override
    public void convertTo(JsonWriter out, Map<K, V> value) {
        final Map<K, V> values = value;
        if (values == null) {
            out.writeNull();
            return;
        }
        if (values.isEmpty()) {
            out.write('{', '}');
            return;
        }
        if (!simpled) out.offer(value);
        out.write('{');
        boolean first = true;
        for (Map.Entry<K, V> en : values.entrySet()) {
            if (!first) out.write(',');
            this.keyencoder.convertTo(out, en.getKey());
            out.write(':');
            this.valencoder.convertTo(out, en.getValue());
            if (first) first = false;
        }
        out.write('}');
        if (!simpled) out.poll();
    }
}
